package cn.edu.cqu.bysj.wm.gui;

import javax.swing.ButtonGroup;
import javax.swing.ButtonModel;
import javax.swing.GroupLayout;
import javax.swing.SwingWorker;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JRadioButton;
import javax.swing.LayoutStyle.ComponentPlacement;

import org.neo4j.graphdb.Direction;

import cn.edu.cqu.bysj.wm.def.ConstDef;
import cn.edu.cqu.bysj.wm.def.ConstDef.AlgorithmType;
import cn.edu.cqu.bysj.wm.gui.ProgressDialog.SwingWorkExecute;
import cn.edu.cqu.bysj.wm.gui.component.AlgorithmTabPane;
import cn.edu.cqu.bysj.wm.gui.component.GNSQAlgorithmTabPane;
import cn.edu.cqu.bysj.wm.gui.component.LPSQAlgorithmTabPane;
import cn.edu.cqu.bysj.wm.gui.component.LPSolutionsAlgorithmTabPane;
import cn.edu.cqu.bysj.wm.gui.model.AlgorithmConfig;
import cn.edu.cqu.bysj.wm.gui.model.AlgorithmResult;
import cn.edu.cqu.bysj.wm.gui.model.SQJDAlgorithm;
import cn.edu.cqu.bysj.wm.gui.result.ExecuteAlgorithm;
import cn.edu.cqu.bysj.wm.gui.result.LPAlgorithmResult;

public class SQConfigUI extends ConfigUi {

	private JRadioButton gnRadioBtn;
	private JRadioButton lpRadionBtn;
	private ButtonGroup bGroup;
	private JLabel gnAlgorithmNote;
	private AlgorithmTabPane panel;

	/**
	 * community config dialog
	 * 
	 * @param parent
	 * @param isModel
	 * @param config
	 */
	public SQConfigUI(MainFrame parent, boolean isModel,
			AlgorithmConfig config) {
		super(parent, isModel);
		this.config = config;

		initContent();
	}

	private void initContent() {
		JLabel label = new JLabel("算法选择");
		gnRadioBtn = new JRadioButton(ConstDef.GN_ALGORITHM_STRING);
		gnRadioBtn.setActionCommand(ConstDef.GN_ALGORITHM_STRING);
		lpRadionBtn = new JRadioButton(ConstDef.LP_ALGORITHM_STRING);
		lpRadionBtn.setSelected(true);
		lpRadionBtn.setActionCommand(ConstDef.LP_ALGORITHM_STRING);
		bGroup = new ButtonGroup();
		bGroup.add(gnRadioBtn);
		bGroup.add(lpRadionBtn);

		gnAlgorithmNote = new JLabel("");
		GroupLayout gl_contentPanel = new GroupLayout(childContent);
		gl_contentPanel
				.setHorizontalGroup(gl_contentPanel
						.createParallelGroup(Alignment.LEADING)
						.addGroup(
								gl_contentPanel
										.createSequentialGroup()
										.addGroup(
												gl_contentPanel
														.createParallelGroup(
																Alignment.LEADING)
														.addGroup(
																gl_contentPanel
																		.createSequentialGroup()
																		.addContainerGap()
																		.addComponent(
																				label)
																		.addPreferredGap(
																				ComponentPlacement.RELATED)
																		.addComponent(
																				gnAlgorithmNote))
														.addGroup(
																gl_contentPanel
																		.createSequentialGroup()
																		.addContainerGap()
																		.addComponent(
																				gnRadioBtn))
														.addGroup(
																gl_contentPanel
																		.createSequentialGroup()
																		.addContainerGap()
																		.addComponent(
																				lpRadionBtn)))
										.addContainerGap(84, Short.MAX_VALUE)));
		gl_contentPanel.setVerticalGroup(gl_contentPanel.createParallelGroup(
				Alignment.LEADING).addGroup(
				gl_contentPanel.createSequentialGroup().addContainerGap()
						.addComponent(label)
						.addPreferredGap(ComponentPlacement.RELATED)
						.addComponent(gnAlgorithmNote).addGap(18)
						.addComponent(gnRadioBtn).addGap(18)
						.addComponent(lpRadionBtn).addGap(120)));
		initExistedConfigure();
		childContent.setLayout(gl_contentPanel);
	}

	private void initExistedConfigure() {
		super.initExistedConfig(config.getSuperConfig());
		if (!config.getDirection().equals(Direction.BOTH)) {
			gnRadioBtn.setEnabled(false);
			gnAlgorithmNote.setText("GN 算法只适用于无向图。");
			lpRadionBtn.setSelected(true);
		}
	}

	@Override
	protected AlgorithmTabPane saveConfig() {
		ButtonModel bm = bGroup.getSelection();
		if (bm == null) {
			// TODO
			JOptionPane.showMessageDialog(this, "请选择算法");
			return null;
		}
		config.setAlgorithmType(AlgorithmType.valueOfType(bm
				.getActionCommand()));
		switch (config.getAlgorithmType()) {
		case GN:
			return new GNSQAlgorithmTabPane(ConstDef.SQ_TYPE_STRING
					+ config.getTitle(), config);
		case LP: {
			if (config.getTime() == 1)
				return new LPSQAlgorithmTabPane(ConstDef.SQ_TYPE_STRING
						+ config.getTitle(), config);
			else {
				return new LPSolutionsAlgorithmTabPane(
						ConstDef.SQ_TYPE_STRING + config.getTitle(),
						config);
			}
		}

		}
		return null;
	}

	@Override
	protected void doAlgorithm() {
		panel = saveConfig();
		if (panel == null) {
			return;
		}
		Task task = new Task();
		setVisible(false);
		@SuppressWarnings("unused")
		ProgressDialog progress = new ProgressDialog(task);
	}

	public class Task extends SwingWorker<Void, Void> implements
			SwingWorkExecute {
		private ProgressDialog progressDialog;

		/*
		 * main task,executed in background thread
		 */
		@Override
		public Void doInBackground() {

			superParent.frame.setEnabled(false);
			SQJDAlgorithm executer = new ExecuteAlgorithm();
			AlgorithmResult result = executer.execute(config);
			if (result instanceof LPAlgorithmResult) {
				config.setLp(((LPAlgorithmResult) result).getLp());
			}
			dispose();
			panel.setResult(result);

			return null;
		}

		/*
		 * executed in event dispatch thread
		 */
		public void done() {
			superParent.getNodeNumber().setText(
					panel.getResult().getNodesNumber() + "");
			superParent.getEdgeNumber().setText(
					panel.getResult().getEdgesNumber() + "");
			superParent.frame.setEnabled(true);
			superParent.prepareJD();
			superParent.addTab(panel.getTitle(), panel);
			panel.showResult();
			progressDialog.dispose();

		}

		public void execute(ProgressDialog progressDialog) {
			super.execute();
			this.progressDialog = progressDialog;
		}
	}
}
